const Koa = require('koa')
const path = require('path')
const fs = require('fs')
const uuid = require('uuid')
const querystring = require('querystring')
const app = new Koa()
// 封装 Buffer 的 split 方法
Buffer.prototype.split = function (sep) {  // 不能用箭头函数
    let index = -1
    let pos = 0
    let len = sep.length
    let parts = []
    while ((index = this.indexOf(sep, pos)) != -1) { 
        parts.push(this.slice(pos, index))
        pos = index + len
    }
    parts.push(this.slice(pos))
    return parts
}

app.use(async (ctx, next) => {
    if (ctx.url == '/user' && ctx.method == 'GET') {
        // ctx.set('Content-Type','text/html;charset=utf8')
        ctx.body = (
            `
                <form method="POST" enctype="multipart/form-data">
                    <input type="text" name="username" />
                    <input type="file" name="avatar" />
                    <input type="submit" />
                </form>
            `
        )
    }else { await next()}
})

app.use(async (ctx, next) => { 
    console.log(ctx.url,'ctx.url');
    
    if (ctx.url == '/user' && ctx.method == 'POST') { 
        let contenttype = ctx.request.headers['content-type']
        console.log(contenttype,'contenttype');
        if (contenttype.includes('multipart/form-data')) { 
            let matches = contenttype.match(/\bboundary=(.+)/)
            let sep = '--' + matches[1]
            console.log(sep, 'sep');
            ctx.body = await getBody(ctx.req,sep)
        }
        
    }else { await next()}
})
/**
 * 异步解析请求体
 */
function getBody(req, sep) { 
    return new Promise((resolve, reject) => { 
        let buffers = []
        req.on('data', data => { 
            buffers.push(data)
        })
        req.on('end', () => {
            let rs = Buffer.concat(buffers)
            let fields = {}
            let lines = rs.split(sep)
            console.log(lines,'lines');
            lines = lines.slice(1,-1)
            lines.forEach(line => { 
                console.log(line,'line');
                let [desc, val] = line.split('\r\n\r\n') // 描述都有两个空行
                desc = desc.toString()
                val = val.slice(0, -2) // 去掉 结尾的 \r\n
                // console.log(desc, 'desc');
                // console.log(val.toString(),'val');
                if (desc.includes('filename')) {
                    let [line1, line2,line3] = desc.split('\r\n')
                    console.log(line2,'line2');
                    console.log(line3, 'line3');
                    let lineObj2 = querystring.parse(line2, '; ')
                    let lineObj3 = querystring.parse(line3, '; ')
                    console.log(lineObj2);
                    
                    let filePath = path.resolve(__dirname,'uploads',uuid.v4())
                    fs.writeFileSync(filePath,val)
                    fields[lineObj2.name] = [
                        {...lineObj2,...lineObj3,filePath}
                    ]
                } else { 
                    let name = querystring.parse(desc, '; ').name.replace(/"/g, '')
                    console.log(name, 'name');
                    fields[name] = val.toString()
                    
                }
            })
            resolve(fields)
        })
    })
}
app.listen(3000)